<template>
  <div :class="wrapperClass">
    <!-- 标签 -->
    <div v-if="label" class="base-select__label">
      <span class="base-select__label-text">{{ label }}</span>
      <span v-if="required" class="base-select__required">*</span>
    </div>

    <!-- 选择器触发器 -->
    <div class="base-select__trigger" @click="handleTriggerClick">
      <div class="base-select__input">
        <span v-if="displayText" class="base-select__value">{{ displayText }}</span>
        <span v-else class="base-select__placeholder">{{ placeholder }}</span>
      </div>
      <van-icon
        :name="visible ? 'arrow-up' : 'arrow-down'"
        class="base-select__arrow"
      />
    </div>

    <!-- 错误信息 -->
    <div v-if="errorMessage" class="base-select__error">
      {{ errorMessage }}
    </div>

    <!-- 弹出层 -->
    <van-popup
      v-model:show="visible"
      position="bottom"
      :style="{ height: popupHeight }"
      round
      closeable
      @close="handleClose"
    >
      <div class="base-select__popup">
        <!-- 标题 -->
        <div class="base-select__popup-header">
          <span class="base-select__popup-title">{{ popupTitle || label || '请选择' }}</span>
        </div>

        <!-- 搜索框 -->
        <div v-if="filterable" class="base-select__search">
          <van-search
            v-model="searchValue"
            placeholder="搜索选项"
            @input="handleSearch"
          />
        </div>

        <!-- 选项列表 -->
        <div class="base-select__options">
          <div
            v-for="option in filteredOptions"
            :key="getOptionValue(option)"
            :class="getOptionClass(option)"
            @click="handleOptionClick(option)"
          >
            <span class="base-select__option-label">{{ getOptionLabel(option) }}</span>
            <van-icon
              v-if="isOptionSelected(option)"
              name="success"
              class="base-select__option-icon"
            />
          </div>
          
          <!-- 空状态 -->
          <div v-if="filteredOptions.length === 0" class="base-select__empty">
            <van-empty description="暂无数据" />
          </div>
        </div>

        <!-- 多选确认按钮 -->
        <div v-if="multiple" class="base-select__actions">
          <van-button
            type="primary"
            block
            @click="handleConfirm"
          >
            确认选择{{ selectedOptions.length > 0 ? `(${selectedOptions.length})` : '' }}
          </van-button>
        </div>
      </div>
    </van-popup>
  </div>
</template>

<script>
import { ref, computed, watch, defineComponent } from 'vue'

export default defineComponent({
  name: 'BaseSelect',
  props: {
    /**
     * 选中值
     */
    modelValue: {
      type: [String, Number, Array],
      default: null
    },
    /**
     * 选项数据
     */
    options: {
      type: Array,
      default: () => []
    },
    /**
     * 标签文本
     */
    label: {
      type: String,
      default: ''
    },
    /**
     * 占位符
     */
    placeholder: {
      type: String,
      default: '请选择'
    },
    /**
     * 是否必填
     */
    required: {
      type: Boolean,
      default: false
    },
    /**
     * 是否禁用
     */
    disabled: {
      type: Boolean,
      default: false
    },
    /**
     * 是否多选
     */
    multiple: {
      type: Boolean,
      default: false
    },
    /**
     * 是否可搜索
     */
    filterable: {
      type: Boolean,
      default: false
    },
    /**
     * 选项值字段名
     */
    valueKey: {
      type: String,
      default: 'value'
    },
    /**
     * 选项标签字段名
     */
    labelKey: {
      type: String,
      default: 'label'
    },
    /**
     * 错误信息
     */
    errorMessage: {
      type: String,
      default: ''
    },
    /**
     * 弹出层标题
     */
    popupTitle: {
      type: String,
      default: ''
    },
    /**
     * 弹出层高度
     */
    popupHeight: {
      type: String,
      default: '50%'
    },
    /**
     * 多选分隔符
     */
    separator: {
      type: String,
      default: '、'
    }
  },
  emits: ['update:modelValue', 'change', 'focus', 'blur'],
  setup(props, { emit }) {
    const visible = ref(false)
    const searchValue = ref('')
    const selectedOptions = ref([])

    /**
     * 容器样式类
     */
    const wrapperClass = computed(() => {
      const classes = ['base-select']
      
      if (props.disabled) classes.push('base-select--disabled')
      if (props.errorMessage) classes.push('base-select--error')
      if (visible.value) classes.push('base-select--focused')
      
      return classes
    })

    /**
     * 显示文本
     */
    const displayText = computed(() => {
      if (props.multiple) {
        if (selectedOptions.value.length === 0) return ''
        return selectedOptions.value
          .map(option => getOptionLabel(option))
          .join(props.separator)
      } else {
        const option = props.options.find(opt => getOptionValue(opt) === props.modelValue)
        return option ? getOptionLabel(option) : ''
      }
    })

    /**
     * 过滤后的选项
     */
    const filteredOptions = computed(() => {
      if (!props.filterable || !searchValue.value) {
        return props.options
      }
      
      return props.options.filter(option => {
        const label = getOptionLabel(option).toLowerCase()
        const search = searchValue.value.toLowerCase()
        return label.includes(search)
      })
    })

    /**
     * 获取选项值
     */
    const getOptionValue = (option) => {
      return typeof option === 'object' ? option[props.valueKey] : option
    }

    /**
     * 获取选项标签
     */
    const getOptionLabel = (option) => {
      return typeof option === 'object' ? option[props.labelKey] : option
    }

    /**
     * 获取选项样式类
     */
    const getOptionClass = (option) => {
      const classes = ['base-select__option']
      
      if (isOptionSelected(option)) {
        classes.push('base-select__option--selected')
      }
      
      return classes
    }

    /**
     * 判断选项是否被选中
     */
    const isOptionSelected = (option) => {
      const value = getOptionValue(option)
      
      if (props.multiple) {
        return selectedOptions.value.some(opt => getOptionValue(opt) === value)
      } else {
        return props.modelValue === value
      }
    }

    /**
     * 触发器点击处理
     */
    const handleTriggerClick = () => {
      if (props.disabled) return
      
      visible.value = true
      emit('focus')
    }

    /**
     * 选项点击处理
     */
    const handleOptionClick = (option) => {
      const value = getOptionValue(option)
      
      if (props.multiple) {
        const index = selectedOptions.value.findIndex(opt => getOptionValue(opt) === value)
        
        if (index > -1) {
          selectedOptions.value.splice(index, 1)
        } else {
          selectedOptions.value.push(option)
        }
      } else {
        emit('update:modelValue', value)
        emit('change', value, option)
        visible.value = false
        emit('blur')
      }
    }

    /**
     * 搜索处理
     */
    const handleSearch = (value) => {
      searchValue.value = value
    }

    /**
     * 确认选择（多选）
     */
    const handleConfirm = () => {
      const values = selectedOptions.value.map(option => getOptionValue(option))
      emit('update:modelValue', values)
      emit('change', values, selectedOptions.value)
      visible.value = false
      emit('blur')
    }

    /**
     * 关闭弹出层
     */
    const handleClose = () => {
      visible.value = false
      searchValue.value = ''
      emit('blur')
    }

    /**
     * 初始化选中选项
     */
    const initSelectedOptions = () => {
      if (props.multiple && Array.isArray(props.modelValue)) {
        selectedOptions.value = props.options.filter(option => {
          return props.modelValue.includes(getOptionValue(option))
        })
      }
    }

    // 监听值变化
    watch(() => props.modelValue, () => {
      initSelectedOptions()
    }, { immediate: true })

    // 监听选项变化
    watch(() => props.options, () => {
      initSelectedOptions()
    })

    return {
      visible,
      searchValue,
      selectedOptions,
      wrapperClass,
      displayText,
      filteredOptions,
      getOptionValue,
      getOptionLabel,
      getOptionClass,
      isOptionSelected,
      handleTriggerClick,
      handleOptionClick,
      handleSearch,
      handleConfirm,
      handleClose
    }
  }
})
</script>

<style lang="scss" scoped>
.base-select {
  position: relative;
  font-size: 14px;

  &__label {
    display: flex;
    align-items: center;
    margin-bottom: 8px;
    font-size: 14px;
    line-height: 20px;
    color: #323233;
  }

  &__label-text {
    flex: 1;
  }

  &__required {
    margin-left: 4px;
    color: #ee0a24;
  }

  &__trigger {
    position: relative;
    display: flex;
    align-items: center;
    padding: 0 16px;
    background-color: #fff;
    border: 1px solid #ebedf0;
    border-radius: 6px;
    cursor: pointer;
    transition: border-color 0.2s;

    &:hover {
      border-color: #c8c9cc;
    }
  }

  &__input {
    flex: 1;
    height: 44px;
    display: flex;
    align-items: center;
  }

  &__value {
    color: #323233;
    font-size: 14px;
    line-height: 1.5;
  }

  &__placeholder {
    color: #c8c9cc;
    font-size: 14px;
    line-height: 1.5;
  }

  &__arrow {
    color: #969799;
    font-size: 16px;
    transition: transform 0.2s;
  }

  &__error {
    margin-top: 4px;
    font-size: 12px;
    line-height: 16px;
    color: #ee0a24;
  }

  &__popup {
    height: 100%;
    display: flex;
    flex-direction: column;
  }

  &__popup-header {
    padding: 16px;
    border-bottom: 1px solid #ebedf0;
  }

  &__popup-title {
    font-size: 16px;
    font-weight: 500;
    color: #323233;
    text-align: center;
  }

  &__search {
    padding: 16px;
    border-bottom: 1px solid #ebedf0;
  }

  &__options {
    flex: 1;
    overflow-y: auto;
  }

  &__option {
    display: flex;
    align-items: center;
    padding: 16px;
    border-bottom: 1px solid #f7f8fa;
    cursor: pointer;
    transition: background-color 0.2s;

    &:hover {
      background-color: #f7f8fa;
    }

    &--selected {
      color: #1989fa;
      background-color: #f0f9ff;
    }
  }

  &__option-label {
    flex: 1;
    font-size: 14px;
    line-height: 20px;
  }

  &__option-icon {
    color: #1989fa;
    font-size: 16px;
  }

  &__empty {
    padding: 32px 16px;
    text-align: center;
  }

  &__actions {
    padding: 16px;
    border-top: 1px solid #ebedf0;
  }

  // 状态
  &--focused {
    .base-select__trigger {
      border-color: #1989fa;
    }
  }

  &--error {
    .base-select__trigger {
      border-color: #ee0a24;
    }
  }

  &--disabled {
    .base-select__trigger {
      background-color: #f7f8fa;
      border-color: #ebedf0;
      cursor: not-allowed;
    }

    .base-select__value,
    .base-select__placeholder {
      color: #c8c9cc;
    }
  }
}
</style>